#ifndef QROUNDABOUT_H
#define QROUNDABOUT_H

#include <QGraphicsView>
#include <QMutex>
#include "branch.h"
#include "rails.h"
#include "barrier.h"
#include "car.h"

class QPainter;
class QColor;
class QLabel;
class QGraphicsItemAnimation;

class QRoundabout : public QGraphicsView
{
Q_OBJECT

public:
    QRoundabout(QWidget *parent = 0, int nLanes = 2, int nBranches = 3,
                int lineWidth = 30, int radius = 200);
    ~QRoundabout();

private:
    qreal _radius;                ///< Promień; Odległość od  (0,0) do zewnętrznej linii ronda. */
    qreal _laneWidth;             ///< Szerokość jednego pasa (zarówno na rondzie jak i gałęziach).*/

    QColor *_backgroundColor;   ///< Kolor tła (trawy).*/

    /**
    @brief Lista zależności między gałęziami.

    Pod indeksem [0] przechowywana jest zależność między gałęziami 0 i 1, pod [1]: między 1 i 2, i tak dalej aż do [n]: między n a 0.
     */
    QList<Dependence> _dependences;
    int _numLanes;              ///< Liczba pasów na rondzie.*/
    int _numBranches;           ///< Liczba gałęzi.*/
    bool _barriersVisible; ///< Czy rysować bariery na rondzie */
    QList<Branch*> _branches;            ///< Jedna gałąź, to jeden obiekt w liście.*/
    QList<Rails*> _rails;                ///< Jedne tory, to jeden obiekt w liście.*/

    QList<Barrier*> _outletBarriers;
    QList<Barrier*> _entryBarriers;
    QList<Barrier*> _changeLaneBarriers;
    QList<Barrier*> _shortcutBarriers;
    QList<Barrier*> _shortcutEndBarriers;

    QList<Car*> _branchesCars; ///< TODO: Można wykorzystać _branchesCars i _rimCars do ograniczenia sprawdzania kolizji */
    QList<Car*> _rimCars;   ///< TODO: Można wykorzystać _branchesCars i _rimCars do ograniczenia sprawdzania kolizji */

    QGraphicsScene *_scene;
    double _wantedScaling;
    double _actualScaling;
    QTimer *_scalingTimer;
    int _numScheduledScalings;
    qreal _scalingsTotal;
    QMutex _scalingMutex;

    void drawRoundabout(QPainter *);
    void drawBranches(QPainter *);
    void drawConnections(QPainter *);
    void drawRails(QPainter *);
    void drawBarriers(QPainter *);
    void showCoords(QPainter *);

protected:
    void drawBackground ( QPainter * painter, const QRectF & rect );
    void wheelEvent ( QWheelEvent * event );
    void mousePressEvent(QMouseEvent *event);

public:
    void makeBasicTraffic();
    void computeBarriers();
    void addBarriers(bool);
    void generatePedestrian(int source);
    int generateCar(int startingLane, int destLane, int from, int to, int rules);

    qreal getRimWidth();
    qreal getRadius();
    int getNumLanes(); //ilosc pasow na rondzie
    qreal getLaneWidth();
    QGraphicsScene* getScene();
    QList<Branch*>* getBranches();
    QList<Barrier*>* getOutletBarriers();
    QList<Barrier*>* getEntryBarriers();
    QList<Barrier*>* getChangeLaneBarriers();
    QList<Barrier*>* getShortcutBarriers();
    QList<Barrier*>* getShortcutEndBarriers();
    QList<Dependence>* getDependences();
    QList<Rails*>* getRails();
    int getNumEntries();
    int getNumOutlets();
    int getNumLanesOnBranch(int i);
    qreal getBranchFi(int);
    bool getBarriersVisable();
    QPointF getCenter() { return mapToScene(viewport()->rect().center()); }

    friend class RSim;

private slots:
    void scalingTime(qreal);
    void animFinished();
};

#endif // QROUNDABOUT_H
